#--
# Copyright (c) 2014 SoftLayer Technologies, Inc. All rights reserved.
#
# For licensing information see the LICENSE.md file in the project root.
#++

module SoftLayer
  #
  # This class allows you to order a Firewall for a VLAN
  #
  class VLANFirewallOrder
    ##
    # The VLAN that you are ordering the firewall for.
    attr_reader :vlan_id

    ##
    # Set high_availability to true if you want redundant
    # firewall devices (defaults to false, no high_availability)
    attr_accessor :high_availability

    ##
    # Create a new order for the given VLAN
    # Note that the vlan_id is NOT the same as the vlan number.
    def initialize (vlan_id, client = nil)
      @softlayer_client = client || Client.default_client
      raise "#{__method__} requires a client but none was given and Client::default_client is not set" if !@softlayer_client

      @vlan_id = vlan_id
      @high_availability = false
    end

    ##
    # Calls the SoftLayer API to verify that the template provided by this order is valid
    # This routine will return the order template generated by the API or will throw an exception
    #
    # This routine will not actually create a Bare Metal Instance and will not affect billing.
    #
    # If you provide a block, it will receive the order template as a parameter and
    # the block may make changes to the template before it is submitted.
    def verify()
      order_template = firewall_order_template
      order_template = yield order_template if block_given?

      @softlayer_client[:Product_Order].verifyOrder(order_template)
    end

    ##
    # Calls the SoftLayer API to place an order for a new server based on the template in this
    # order. If this succeeds then you will be billed for the new server.
    #
    # If you provide a block, it will receive the order template as a parameter and
    # the block may make changes to the template before it is submitted.
    def place_order!()
      order_template = firewall_order_template
      order_template = yield order_template if block_given?

      @softlayer_client[:Product_Order].placeOrder(order_template)
    end

    protected

    ##
    # Returns a hash of the creation options formatted to be sent to
    # the SoftLayer API for either verification or completion
    def firewall_order_template
      client = @softlayer_client
      additional_products_package = SoftLayer::ProductPackage.additional_products_package(client)

      template = {
          'complexType' => 'SoftLayer_Container_Product_Order_Network_Protection_Firewall_Dedicated',
          'quantity' => 1,
          'packageId' => additional_products_package.id,
          'vlanId' => @vlan_id
        }

      if @high_availability
        expected_description = "Hardware Firewall (High Availability)"
      else
        expected_description = "Hardware Firewall (Dedicated)"
      end

      firewall_items = additional_products_package.items_with_description(expected_description)

      raise "Could not find a price item matching the description '#{expected_description}'" if firewall_items.empty?

      firewall_item = firewall_items[0]

      template['prices'] = [{ 'id' => firewall_item.price_id }] if firewall_item.respond_to?(:price_id)

      template
    end
  end # class VLANFirewallOrder
end # module SoftLayer
